import 'package:dio/dio.dart';

import 'http_code.dart';

import 'http_handle_error.dart';
import 'http_response.dart';

extension HttpCore on Dio {
  Future<HttpResponse> postRequest<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  }) async {
    return post(
      path,
      data: data,
      queryParameters: queryParameters,
      options: options,
      cancelToken: cancelToken,
      onSendProgress: onSendProgress,
      onReceiveProgress: onReceiveProgress,
    ).then(_handleResponse, onError: _handleDioException);
  }

  Future<HttpResponse> putRequest<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  }) async {
    return put(
      path,
      data: data,
      queryParameters: queryParameters,
      options: options,
      cancelToken: cancelToken,
      onSendProgress: onSendProgress,
      onReceiveProgress: onReceiveProgress,
    ).then(_handleResponse, onError: _handleDioException);
  }

  Future<HttpResponse> deleteRequest<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
  }) async {
    return delete(
      path,
      data: data,
      queryParameters: queryParameters,
      options: options,
      cancelToken: cancelToken,
    ).then(_handleResponse, onError: _handleDioException);
  }

  Future<HttpResponse> getRequest<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  }) async {
    return get(
      path,
      data: data,
      queryParameters: queryParameters,
      options: options,
      cancelToken: cancelToken,
      onReceiveProgress: onReceiveProgress,
    ).then(_handleResponse, onError: _handleDioException);
  }

  Future<HttpResponse> _handleDioException(error) async {
    DioException exception = error;
    DioExceptionType type = exception.type;
    // if (type == DioExceptionType.connectionError ) {
    //   await HttpConnectionCheck.checkNetWork(listen: false);
    // }
    // if (type == DioExceptionType.unknown) {
    //   await HttpConnectionCheck.checkNetWork(listen: false);
    //   if (isNoNetWork) {
    //     type = DioExceptionType.connectionError;
    //   }
    // }
    HttpResponse response =
        HttpResponse(type: type, message: exception.message);
    response = HttpHandleError.adjust(response, exception: exception);
    return response;
  }

  Future<HttpResponse> _handleResponse(Response<dynamic> response) async {
    if (response.statusCode != HttpCode.code200) {
      HttpResponse baseResponse = HttpResponse(
        status: response.statusCode,
        message: response.statusMessage,
      );
      baseResponse = HttpHandleError.adjust(baseResponse);
      return Future.value(baseResponse);
    } else {
      HttpResponse baseResponse = HttpResponse.fromJson(response.data);
      if (baseResponse.status == HttpCode.code200) {
        baseResponse.data ??= {};
        return Future.value(baseResponse);
      } else {
        baseResponse = HttpHandleError.adjust(baseResponse);
        return Future.value(baseResponse);
      }
    }
  }
}
